Flutter GPUSurfaceGL
GPUSurfaceGL 类是对 Flutter Surface 在 OpenGL 下的实现。该类位于 src/flutter/shell/gpu/gpu_surface_gl.h。
MakeGLContext
在该方法中,调用 skia 的初始化,创建出 OpenGL 下的 GrDirectContext:
sk_sp<GrDirectContext> GPUSurfaceGL::MakeGLContext(GPUSurfaceGLDelegate* delegate) {
    auto context_switch = delegate->GLContextMakeCurrent();
    // ...
    const auto options =
        MakeDefaultContextOptionskRender, GrBackendApi::kOpenGL;
    auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options);
	// ...
    context->setResourceCacheLimits(kGrCacheMaxCount, kGrCacheMaxByteSize);
	// ...
    return context;
}
Skia 通过 GrDirectContext 类管理 GPU,有了 GrDirectContext,就能够用它创建 SkSurface 等绘制对象了。
谁调用 MakeGLContext?
GPUSurfaceGL 的构造函数:
GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
    : GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
  context_owner_ = true;
}
在 AndroidSurfaceGL 中,有一个 CreateGPUSurface 方法,如果传入的 GrDirectContext 为空,则会调用这里的方法创建一个:
std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
    GrDirectContext* gr_context) {
  if (gr_context) {
    return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
  } else {
    sk_sp<GrDirectContext> main_skia_context =
        GLContextPtr()->GetMainSkiaContext();
    if (!main_skia_context) {
      main_skia_context = GPUSurfaceGL::MakeGLContext(this);
      GLContextPtr()->SetMainSkiaContext(main_skia_context);
    }
    return std::make_unique<GPUSurfaceGL>(main_skia_context, this, true);
  }
}
构造方法
GPUSurfaceGL 拥有两个构造方法,区别在于 GrDirectContext 是否由自己创建,并且使用 context_owner_ 成员标量表征是否是自己创建的。
GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
	// 创建 `GrDirectContext` 对象
	// 调用第二个构造函数
    : GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
  context_owner_ = true;
}
GPUSurfaceGL::GPUSurfaceGL(sk_sp<GrDirectContext> gr_context,
                           GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
    : delegate_(delegate),
      context_(gr_context),
      context_owner_(false),
      render_to_surface_(render_to_surface),
      weak_factory_(this) {
  // 尝试将OpenGL上下文切换到delegate_
  auto context_switch = delegate_->GLContextMakeCurrent();
  // 检查切换是否成功
  if (!context_switch->GetResult()) {
    FML_LOG(ERROR)
        << "Could not make the context current to set up the Gr context.";
    return;
  }
  delegate_->GLContextClearCurrent();
  // 表示这个 GPUSurfaceGL 是否有效
  valid_ = gr_context != nullptr;
}
其中:GLContextMakeCurrent 到 GLContextClearCurrent 的作用是:
GLContextMakeCurrent和GLContextClearCurrent的调用是为了在设置GrDirectContext(即gr_context)时,确保正确的OpenGL上下文是当前活动的。
GLContextMakeCurrent的调用是为了将OpenGL上下文切换到delegate_。这是因为在设置GrDirectContext时,需要确保正确的OpenGL上下文是当前活动的。如果不这样做,可能会在错误的上下文中设置GrDirectContext,导致渲染错误。
然后,代码检查上下文切换是否成功。如果上下文切换失败,那么就记录一条错误日志并返回,不再执行后续的代码。
如果上下文切换成功,那么就调用GLContextClearCurrent来清除当前的OpenGL上下文。这是因为在设置完GrDirectContext后,不再需要OpenGL上下文,所以将其清除以防止后续的代码错误地使用这个上下文。
总的来说,GLContextMakeCurrent和GLContextClearCurrent的调用是为了确保在设置GrDirectContext时,正确的OpenGL上下文是当前活动的,并在设置完GrDirectContext后,清除当前的OpenGL上下文。
本文作者:Maeiee
本文链接:Flutter GPUSurfaceGL
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!
